﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BoolanSlide.RedoUndo;
using Windows.UI;
using Windows.UI.Text;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media;

namespace BoolanElement.UI.Shapes.TextBoxShapes
{
    public class ShapesController:IShapesStyleController,ITextStyleController
    {
        private BooTextShapesBase ShapeBase;

        public ShapesController(BooTextShapesBase shapesBase)
        {
            ShapeBase = shapesBase;
        }

        public void ChangeFontSizeTo(double size,bool shouldSaveForRedoUndo=false)
        {  
            ITextSelection selectedText = ShapeBase.TextBox.Document.Selection;
            if (selectedText != null && selectedText.Text != String.Empty)
            {
                checked
                {
                    ITextCharacterFormat format = selectedText.CharacterFormat;
                    format.Size = (float)size;
                    selectedText.CharacterFormat = format;
                }
            }
            else
            {
                checked
                {
                    ITextCharacterFormat defaultFormat = ShapeBase.TextBox.Document.GetDefaultCharacterFormat();
                    defaultFormat.Size = (float)size;
                    ShapeBase.TextBox.Document.SetDefaultCharacterFormat(defaultFormat);
                }
            }
        }

        public double GetFontSize()
        {
            double size;
            ITextSelection selectedText = ShapeBase.TextBox.Document.Selection;
            if (selectedText != null && selectedText.Text != String.Empty)
            {
                checked
                {
                    ITextCharacterFormat format = selectedText.CharacterFormat;
                    size = format.Size;
                }
            }
            else
            {
                checked
                {
                    ITextCharacterFormat defaultFormat = ShapeBase.TextBox.Document.GetDefaultCharacterFormat();

                    size = defaultFormat.Size;
                }
            }
            if (size < 0)
                size = 22;
            return size;
        }

        public void ChangeFontBoldStatusTo(FormatEffect status)
        {    
            ITextSelection selectedText = ShapeBase.TextBox.Document.Selection;
            if (selectedText != null && selectedText.Text != String.Empty)
            {
                ITextCharacterFormat format = selectedText.CharacterFormat;
                format.Bold = status;
                selectedText.CharacterFormat = format;
            }
            else
            {
                ITextCharacterFormat defaultFormat = ShapeBase.TextBox.Document.GetDefaultCharacterFormat();
                defaultFormat.Bold = status;
                ShapeBase.TextBox.Document.SetDefaultCharacterFormat(defaultFormat);
            }
        }

        public FormatEffect GetFontBoldStatus()
        {
            FormatEffect formatEffect;

            ITextSelection selectedText = ShapeBase.TextBox.Document.Selection;
            if (selectedText != null && selectedText.Text != String.Empty)
            {
                ITextCharacterFormat format = selectedText.CharacterFormat;
                formatEffect = format.Bold;
            }
            else
            {
                ITextCharacterFormat defaultFormat = ShapeBase.TextBox.Document.GetDefaultCharacterFormat();
                formatEffect = defaultFormat.Bold;
            }
            return formatEffect;
        }

        public void ChangeFontItalicStatusTo(FormatEffect status)
        {
            ITextSelection selectedText = ShapeBase.TextBox.Document.Selection;
            if (selectedText != null && selectedText.Text != String.Empty)
            {
                ITextCharacterFormat format = selectedText.CharacterFormat;
                format.Italic = status;
                selectedText.CharacterFormat = format;
            }
            else
            {
                ITextCharacterFormat defaultFormat = ShapeBase.TextBox.Document.GetDefaultCharacterFormat();
                defaultFormat.Italic = status;
                ShapeBase.TextBox.Document.SetDefaultCharacterFormat(defaultFormat);
            }
        }

        public FormatEffect GetFontItalicStatus()
        {
            FormatEffect formatEffect;
            ITextSelection selectedText = ShapeBase.TextBox.Document.Selection;
            if (selectedText != null && selectedText.Text != String.Empty)
            {
                ITextCharacterFormat format = selectedText.CharacterFormat;
                formatEffect = format.Italic; 
            }
            else
            {
                ITextCharacterFormat defaultFormat = ShapeBase.TextBox.Document.GetDefaultCharacterFormat();
                formatEffect = defaultFormat.Italic; 
            }
            return formatEffect;
        }

        public void ChangeFontUnderLineStatusTo(UnderlineType status)
        {
            ITextSelection selectedText = ShapeBase.TextBox.Document.Selection;
            if (selectedText != null && selectedText.Text != String.Empty)
            {
                ITextCharacterFormat format = selectedText.CharacterFormat;
                format.Underline = status;
                selectedText.CharacterFormat = format;
            }
            else
            {
                ITextCharacterFormat defaultFormat = ShapeBase.TextBox.Document.GetDefaultCharacterFormat();
                defaultFormat.Underline = status;
                ShapeBase.TextBox.Document.SetDefaultCharacterFormat(defaultFormat);
            }
        }

        public UnderlineType GetFontUnderLineStatus()
        {
            UnderlineType formatEffect;
            ITextSelection selectedText = ShapeBase.TextBox.Document.Selection;
            if (selectedText != null && selectedText.Text != String.Empty)
            {
                ITextCharacterFormat format = selectedText.CharacterFormat;
                formatEffect = format.Underline;
            }
            else
            {
                ITextCharacterFormat defaultFormat = ShapeBase.TextBox.Document.GetDefaultCharacterFormat();
                formatEffect = defaultFormat.Underline;
            }
            return formatEffect; 
        }

        public void ChangeFontStrikethroughStatusTo(FormatEffect status)
        {
            ITextSelection selectedText = ShapeBase.TextBox.Document.Selection;
            if (selectedText != null && selectedText.Text != String.Empty)
            {
                ITextCharacterFormat format = selectedText.CharacterFormat;
                format.Strikethrough = status;
                selectedText.CharacterFormat = format;
            }
            else
            {
                ITextCharacterFormat defaultFormat = ShapeBase.TextBox.Document.GetDefaultCharacterFormat();
                defaultFormat.Strikethrough = status;
                ShapeBase.TextBox.Document.SetDefaultCharacterFormat(defaultFormat);
            }
        }

        public FormatEffect GetFontStrikethroughStatus()
        {
            FormatEffect formatEffect;
            ITextSelection selectedText = ShapeBase.TextBox.Document.Selection;
            if (selectedText != null && selectedText.Text != String.Empty)
            {
                ITextCharacterFormat format = selectedText.CharacterFormat;
                formatEffect = format.Strikethrough;
            }
            else
            {
                ITextCharacterFormat defaultFormat = ShapeBase.TextBox.Document.GetDefaultCharacterFormat();
                formatEffect = defaultFormat.Strikethrough;
            }
            return formatEffect;
        }

        public void ChangeFontColorTo(Color color)
        {
            ITextSelection selectedText = ShapeBase.TextBox.Document.Selection;
            if (selectedText != null && selectedText.Text != String.Empty)
            {
                ITextCharacterFormat format = selectedText.CharacterFormat;
                format.ForegroundColor = color;
                selectedText.CharacterFormat = format;
            }
            else
            {
                ITextCharacterFormat defaultFormat = ShapeBase.TextBox.Document.GetDefaultCharacterFormat();
                defaultFormat.ForegroundColor = color;
                ShapeBase.TextBox.Document.SetDefaultCharacterFormat(defaultFormat);
            }

        }

        public Color GetFontColor()
        {
            Color color;
            ITextSelection selectedText = ShapeBase.TextBox.Document.Selection;
            if (selectedText != null && selectedText.Text != String.Empty)
            {
                ITextCharacterFormat format = selectedText.CharacterFormat;
                color = format.ForegroundColor;
            }
            else
            {
                ITextCharacterFormat defaultFormat = ShapeBase.TextBox.Document.GetDefaultCharacterFormat();
                color = defaultFormat.ForegroundColor;
            }
            return color;
        }

        public void ChangeFontFamilyTo(string family)
        {
            ITextSelection selectedText = ShapeBase.TextBox.Document.Selection;
            if (selectedText != null && selectedText.Text != String.Empty)
            {
                ITextCharacterFormat format = selectedText.CharacterFormat;
                format.Name = family;
                selectedText.CharacterFormat = format;
            }
            else
            {
                ITextCharacterFormat defaultFormat = ShapeBase.TextBox.Document.GetDefaultCharacterFormat();
                defaultFormat.Name = family;
                ShapeBase.TextBox.Document.SetDefaultCharacterFormat(defaultFormat);
            }
        }

        public string GetFontFamily()
        {
            string familyName;
            ITextSelection selectedText = ShapeBase.TextBox.Document.Selection;
            if (selectedText != null && selectedText.Text != String.Empty)
            {
                ITextCharacterFormat format = selectedText.CharacterFormat;
                familyName = format.Name;
                selectedText.CharacterFormat = format;
            }
            else
            {
                ITextCharacterFormat defaultFormat = ShapeBase.TextBox.Document.GetDefaultCharacterFormat();
                familyName = defaultFormat.Name;
                ShapeBase.TextBox.Document.SetDefaultCharacterFormat(defaultFormat);
            }
            return familyName;
        }

        public void ChangeFontAlignmentTo(Configuration.TextAlignment alignment)
        {
           switch (alignment)
            {
                case Configuration.TextAlignment.LeftTop: ChangeTextLeftTop(); break;
                case Configuration.TextAlignment.CenterTop: ChangeCenterTop(); break;
                case Configuration.TextAlignment.RightTop: ChangeRightTop(); break;
                case Configuration.TextAlignment.LeftCenter: ChangeLeftCenter(); break;
                case Configuration.TextAlignment.CenterCenter: ChangeCenterCenter(); break;
                case Configuration.TextAlignment.RightCenter: ChangeRightCenter(); break;
                case Configuration.TextAlignment.LeftBottom: ChangeLeftBottom(); break;
                case Configuration.TextAlignment.CenterBottom: ChangeCenterBottom(); break;
                case Configuration.TextAlignment.RightBottom: ChangeRightBottom(); break;
                default: throw new Exception();
            }
        }

        public Configuration.TextAlignment GetFontAlignment()
        {
            return ShapeBase.TextShapesBaseElement.TextAlignment;
        }

        public void ChangeShapeStyleTo(Configuration.ShapeStyle style)
        {
            if (style == Configuration.ShapeStyle.NoBorderNoBKG)
            {
                ShapeBase.Shape.Fill = new SolidColorBrush(Colors.Transparent);
                ShapeBase.Shape.StrokeThickness = 0;
                ShapeBase.Shape.Stroke = new SolidColorBrush(Colors.Transparent); 
            }
            else if (style == Configuration.ShapeStyle.BorderNoBKG)
            {
                ShapeBase.Shape.Fill = new SolidColorBrush(Colors.Transparent);
                ShapeBase.Shape.Stroke = new SolidColorBrush(Color.FromArgb(255, 24, 122, 169));
                ShapeBase.Shape.StrokeThickness = 1;
            }
            else if (style == Configuration.ShapeStyle.NoBorderBKG)
            {
                ShapeBase.Shape.StrokeThickness = 0;
                ShapeBase.Shape.Fill = new SolidColorBrush(Color.FromArgb(255, 24, 122, 169));
            }
            else if (style == Configuration.ShapeStyle.BorderBKG)
            {
                ShapeBase.Shape.StrokeThickness = 5;
                ShapeBase.Shape.Stroke = new SolidColorBrush(Color.FromArgb(255, 24, 122, 169));
                ShapeBase.Shape.Fill = new SolidColorBrush(Color.FromArgb(255, 146, 208, 81));
            }

            ShapeBase.TextShapesBaseElement.ShapeFillColor = ((SolidColorBrush)ShapeBase.Shape.Fill).Color;
            ShapeBase.TextShapesBaseElement.BorderWidth = ShapeBase.Shape.StrokeThickness;
            ShapeBase.TextShapesBaseElement.BorderColor = ((SolidColorBrush)ShapeBase.Shape.Stroke).Color;

            ShapeBase.TextShapesBaseElement.ShapeStyle = style;
        }

        public Configuration.ShapeStyle GetShapeStyle()
        {
            return ShapeBase.TextShapesBaseElement.ShapeStyle;
        }

        public virtual void ChangeShapeFillColorTo(Color color)
        {
            ShapeBase.Shape.Fill = new SolidColorBrush(color);
        }

        public Color GetShapeFillColor()
        {
            return ((SolidColorBrush)ShapeBase.Shape.Fill).Color;
        }

        public void ChangeBorderColorTo(Color color)
        {
            ShapeBase.Shape.Stroke = new SolidColorBrush(color);
        }

        public Color GetBorderColor()
        {
            return ((SolidColorBrush)ShapeBase.Shape.Stroke).Color;
        }

        public void ChangeBorderWidthTo(double width)
        {
            ShapeBase.Shape.StrokeThickness = width;
        }

        public double GetBorderWidth()
        {
            return ShapeBase.Shape.StrokeThickness;
        }

        #region 修改文本对齐方式
        public void ChangeTextLeftTop()
        {
            ITextRange searchRange = ShapeBase.TextBox.Document.GetRange(0, TextConstants.MaxUnitCount);
            searchRange.ParagraphFormat.Alignment = ParagraphAlignment.Left;
            
            ShapeBase.CenterStack.HorizontalAlignment = HorizontalAlignment.Left;
            ShapeBase.CenterStack.VerticalAlignment = VerticalAlignment.Top;

            ShapeBase.TextShapesBaseElement.TextAlignment = Configuration.TextAlignment.LeftTop;
        }

        public void ChangeCenterTop()
        {
            ITextRange searchRange = ShapeBase.TextBox.Document.GetRange(0, TextConstants.MaxUnitCount);
            searchRange.ParagraphFormat.Alignment = ParagraphAlignment.Center;
            
            ShapeBase.CenterStack.HorizontalAlignment = HorizontalAlignment.Center;
            ShapeBase.CenterStack.VerticalAlignment = VerticalAlignment.Top;

            ShapeBase.TextShapesBaseElement.TextAlignment = Configuration.TextAlignment.CenterTop;
        }

        public void ChangeRightTop()
        {
            ITextRange searchRange = ShapeBase.TextBox.Document.GetRange(0, TextConstants.MaxUnitCount);
            searchRange.ParagraphFormat.Alignment = ParagraphAlignment.Right;            

            ShapeBase.CenterStack.HorizontalAlignment = HorizontalAlignment.Right;
            ShapeBase.CenterStack.VerticalAlignment = VerticalAlignment.Top;

            ShapeBase.TextShapesBaseElement.TextAlignment = Configuration.TextAlignment.RightTop;
        }

        public void ChangeLeftCenter()
        {
            ITextRange searchRange = ShapeBase.TextBox.Document.GetRange(0, TextConstants.MaxUnitCount);
            searchRange.ParagraphFormat.Alignment = ParagraphAlignment.Left;

            ShapeBase.CenterStack.HorizontalAlignment = HorizontalAlignment.Left;
            ShapeBase.CenterStack.VerticalAlignment = VerticalAlignment.Center;

            ShapeBase.TextShapesBaseElement.TextAlignment = Configuration.TextAlignment.LeftCenter;
        }

        public void ChangeCenterCenter()
        {
            ITextRange searchRange = ShapeBase.TextBox.Document.GetRange(0, TextConstants.MaxUnitCount);
            searchRange.ParagraphFormat.Alignment = ParagraphAlignment.Center;

            ShapeBase.CenterStack.HorizontalAlignment = HorizontalAlignment.Center;
            ShapeBase.CenterStack.VerticalAlignment = VerticalAlignment.Center;

            ShapeBase.TextShapesBaseElement.TextAlignment = Configuration.TextAlignment.CenterCenter;
        }

        public void ChangeRightCenter()
        {
            ITextRange searchRange = ShapeBase.TextBox.Document.GetRange(0, TextConstants.MaxUnitCount);
            searchRange.ParagraphFormat.Alignment = ParagraphAlignment.Right;            

            ShapeBase.CenterStack.HorizontalAlignment = HorizontalAlignment.Right;
            ShapeBase.CenterStack.VerticalAlignment = VerticalAlignment.Center;

            ShapeBase.TextShapesBaseElement.TextAlignment = Configuration.TextAlignment.RightCenter;
        }

        public void ChangeLeftBottom()
        {
            ITextRange searchRange = ShapeBase.TextBox.Document.GetRange(0, TextConstants.MaxUnitCount);
            searchRange.ParagraphFormat.Alignment = ParagraphAlignment.Left;

            ShapeBase.CenterStack.HorizontalAlignment = HorizontalAlignment.Left;
            ShapeBase.CenterStack.VerticalAlignment = VerticalAlignment.Bottom;

            ShapeBase.TextShapesBaseElement.TextAlignment = Configuration.TextAlignment.LeftBottom;
        }

        public void ChangeCenterBottom()
        {
            ITextRange searchRange = ShapeBase.TextBox.Document.GetRange(0, TextConstants.MaxUnitCount);
            searchRange.ParagraphFormat.Alignment = ParagraphAlignment.Center;

            ShapeBase.CenterStack.HorizontalAlignment = HorizontalAlignment.Center;
            ShapeBase.CenterStack.VerticalAlignment = VerticalAlignment.Bottom;

            ShapeBase.TextShapesBaseElement.TextAlignment = Configuration.TextAlignment.CenterBottom;
        }

        public void ChangeRightBottom()
        {
            ITextRange searchRange = ShapeBase.TextBox.Document.GetRange(0, TextConstants.MaxUnitCount);
            searchRange.ParagraphFormat.Alignment = ParagraphAlignment.Right;

            ShapeBase.CenterStack.HorizontalAlignment = HorizontalAlignment.Right;
            ShapeBase.CenterStack.VerticalAlignment = VerticalAlignment.Bottom;

            ShapeBase.TextShapesBaseElement.TextAlignment = Configuration.TextAlignment.RightBottom;
        }
        #endregion 修改文本对齐方式


        public void ChangeZIndexTo(int index)
        {
            this.ShapeBase.TextShapesBaseElement.ElementTransform.ZIndex = index;
        }

        public int GetZIndex()
        {
            return this.ShapeBase.TextShapesBaseElement.ElementTransform.ZIndex;
        }


        public void ChangeBorderWidthCompleted()
        {
            RedoUndoHelper.SaveStatus(ShapeBase);
        }


        public void ChangeListStyleTo(BoolanSlide.UIElement.TextBox.TextListStyleArgs TextListStyle)
        {

        }
    }
}
